package com.zh.juc.completablefuture;

import lombok.Getter;
import sun.nio.ch.Net;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: zhanghuan
 * @date: 2022/10/7 14:31
 * @description: create it
 * <p>
 * 同一款产品，同时搜索出同款产品在各大电商平台的售价
 * 同一款产品，同时搜索本产品在同一个电商平台下，各个入驻卖家售价多少
 * 输出：结果是同款产品在不同地方的价格清单列表，返回List<String>
 * <<mysql>> in jd price is 87.22
 * <<mysql>> in taobao price is 81.22
 * <<mysql>> in dangdang price is 76.22
 */
public class CompletableFutureMall {

    static List<NetMall> list = Arrays.asList(
            new NetMall("jd"),
            new NetMall("dangdang"),
            new NetMall("taobao"),
            new NetMall("pdd"),
            new NetMall("deiwu")
    );

    /**
     * 一家一家搜
     *
     * @param list
     * @param productName
     * @return
     */
    public static List<String> getPrice(List<NetMall> list, String productName) {
//        List<String> collect = list.stream().map(netMall -> {
//            return String.format(productName + "in %s price is %.2f", netMall.getNetMallName(), netMall.calcPrice(productName));
//        }).collect(Collectors.toList());
//        return collect;
        List<String> collect = list.stream().map(netMall ->
                        String.format(productName + "in %s price is %.2f", netMall.getNetMallName(), netMall.calcPrice(productName)))
                .collect(Collectors.toList());
        return collect;
    }

    /**
     * 异步执行
     *
     * @param list
     * @param productName
     * @return
     */
    public static List<String> getPriceByCompletableFuture(List<NetMall> list, String productName) {
        List<String> collect = list.stream().map(netMall ->
                        CompletableFuture.supplyAsync(() -> String.format(productName + "in %s price is %.2f",
                                netMall.getNetMallName(),
                                netMall.calcPrice(productName))))
                .collect(Collectors.toList())
                .stream()
                .map(s -> s.join())
                .collect(Collectors.toList());
        return collect;
    }

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        List<String> list1 = getPrice(list, "mysql");
        for (String element : list1) {
            System.out.println(element);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("cost time------->" + (endTime - startTime) + "毫秒");
        System.out.println("---------------------");
        long startTime2 = System.currentTimeMillis();
        List<String> list2 = getPriceByCompletableFuture(list, "mysql");
        for (String element : list2) {
            System.out.println(element);
        }
        long endTime2 = System.currentTimeMillis();
        System.out.println("cost time------->" + (endTime2 - startTime2) + "毫秒");

    }
}

class NetMall {
    @Getter
    private String netMallName;

    public NetMall(String netMallName) {
        this.netMallName = netMallName;
    }

    public double calcPrice(String productName) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
    }
}
